package com.liujit.pay.wx.kit;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import com.liujit.pay.wx.api.WxOrderApi;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 请求工具类
 * @author: liujun
 * @create: 2021-02-20 16:07
 */
public class HttpKit {

    private static final String OS = System.getProperty("os.name") + "/" + System.getProperty("os.version");
    private static final String VERSION = System.getProperty("java.version");

    /**
     * get 请求
     *
     * @param url     请求url
     * @param params  请求参数
     * @param headers 请求头
     * @return 请求返回的结果
     */
    public static String get(String url, Map<String, Object> params, Map<String, String> headers) {
        return HttpRequest.get(url).form(params).headerMap(headers, true).execute().body();
    }

    /**
     * get 请求
     *
     * @param url           请求url
     * @param authorization 授权信息
     * @param serialNo      公钥证书序列号
     * @param params        请求参数
     * @return 请求返回的结果
     */
    public static String get(String url, String authorization, String serialNo, Map<String, Object> params) {
        return get(url, params, getHeaders(authorization, serialNo));
    }

    /**
     * get 请求
     *
     * @param url     请求url
     * @param headers 请求头
     * @return 请求返回的结果
     */
    public static String get(String url, Map<String, String> headers) {
        return HttpRequest.get(url).headerMap(headers, true).execute().body();
    }

    /**
     * get 请求
     *
     * @param url           请求url
     * @param authorization 授权信息
     * @param serialNo      公钥证书序列号
     * @return 请求返回的结果
     */
    public static String get(String url, String authorization, String serialNo) {
        return get(url, getHeaders(authorization, serialNo));
    }

    /**
     * post 请求
     *
     * @param url     请求url
     * @param body    请求参数
     * @param headers 请求头
     * @return 请求返回的结果
     */
    public static String post(String url, String body, Map<String, String> headers) {
        return HttpRequest.post(url).body(body).headerMap(headers, true).execute().body();
    }

    /**
     * post 请求
     *
     * @param url           请求url
     * @param authorization 授权信息
     * @param serialNo      公钥证书序列号
     * @param body          请求参数
     * @return 请求返回的结果
     */
    public static String post(String url, String authorization, String serialNo, String body) {
        return post(url, body, getHeaders(authorization, serialNo));
    }

    /**
     * delete 请求
     *
     * @param url     请求url
     * @param body    请求参数
     * @param headers 请求头
     * @return 请求返回的结果
     */
    public static String delete(String url, String body, Map<String, String> headers) {
        return HttpRequest.delete(url).body(body).headerMap(headers, true).execute().body();
    }

    /**
     * delete 请求
     *
     * @param url           请求url
     * @param authorization 授权信息
     * @param serialNo      公钥证书序列号
     * @param body          请求参数
     * @return 请求返回的结果
     */
    public static String delete(String url, String authorization, String serialNo, String body) {
        return delete(url, body, getHeaders(authorization, serialNo));
    }

    /**
     * upload 请求
     *
     * @param url     请求url
     * @param params  请求参数
     * @param headers 请求头
     * @return 请求返回的结果
     */
    public static String upload(String url, Map<String, Object> params, Map<String, String> headers) {
        return HttpRequest.post(url).form(params).headerMap(headers, true).execute().body();
    }

    /**
     * upload 请求
     *
     * @param url           请求url
     * @param authorization 授权信息
     * @param serialNo      公钥证书序列号
     * @param body          请求参数
     * @param file          上传文件
     * @return 请求返回的结果
     */
    public static String upload(String url, String authorization, String serialNo, String body, File file) {
        Map<String, Object> paramMap = new HashMap<>(2);
        paramMap.put("file", file);
        paramMap.put("meta", body);
        return upload(url, paramMap, getUploadHeaders(authorization, serialNo));
    }


    /**
     * put 请求
     *
     * @param url     请求url
     * @param body    请求参数
     * @param headers 请求头
     * @return 请求返回的结果
     */
    public static String put(String url, String body, Map<String, String> headers) {
        return HttpRequest.put(url).body(body).headerMap(headers, true).execute().body();
    }

    /**
     * put 请求
     *
     * @param url           请求url
     * @param authorization 授权信息
     * @param serialNo      公钥证书序列号
     * @param body          请求参数
     * @return 请求返回的结果
     */
    public static String put(String url, String authorization, String serialNo, String body) {
        return put(url, body, getHeaders(authorization, serialNo));
    }

    private static Map<String, String> getHeaders(String authorization, String serialNumber) {
        Map<String, String> headers = getBaseHeaders(authorization);
        headers.put("Content-Type", ContentType.JSON.getValue());
        if (StrUtil.isNotEmpty(serialNumber)) {
            headers.put("Wechatpay-Serial", serialNumber);
        }
        return headers;
    }

    private static Map<String, String> getBaseHeaders(String authorization) {
        String userAgent = String.format(
                "WeChatPay-HttpClient/%s (%s) Java/%s",
                WxOrderApi.class.getPackage().getImplementationVersion(),
                OS,
                VERSION == null ? "Unknown" : VERSION);

        Map<String, String> headers = new HashMap<>(5);
        headers.put("Accept", ContentType.JSON.getValue());
        headers.put("Authorization", authorization);
        headers.put("User-Agent", userAgent);
        return headers;
    }

    private static Map<String, String> getUploadHeaders(String authorization, String serialNumber) {
        Map<String, String> headers = getBaseHeaders(authorization);
        headers.put("Content-Type", "multipart/form-data;boundary=\"boundary\"");
        if (StrUtil.isNotEmpty(serialNumber)) {
            headers.put("Wechatpay-Serial", serialNumber);
        }
        return headers;
    }
}
